package yb.ecp.fast.user.service;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import yb.ecp.fast.infra.infra.log.LogHelper;
import yb.ecp.fast.infra.util.ListUtil;
import yb.ecp.fast.infra.util.Ref;
import yb.ecp.fast.infra.util.StringUtil;
import yb.ecp.fast.user.dao.entity.DepartmentDO;
import yb.ecp.fast.user.dao.mapper.DepartmentMapper;
import yb.ecp.fast.user.dao.mapper.ProfileMapper;
import yb.ecp.fast.user.dao.mapper.RoleMapper;
import yb.ecp.fast.user.infra.AuthConstant;
import yb.ecp.fast.user.infra.ErrorCode;
import yb.ecp.fast.user.manager.UserContextManager;
import yb.ecp.fast.user.service.VO.DepartmentVO;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by GYJ on 2017-08-25.
 */
@Service
public class DepartmentService
{
    @Autowired
    private DepartmentMapper departmentMapper;

    @Autowired
    ProfileService profileService;

    @Autowired
    ProfileMapper profileMapper;
    
    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private UserContextManager userContextManager;
    
    /**
     * 返回下级机构列表
     *
     * @param deptId 上级ID
     * @return 部门集合
     */
    public List<DepartmentVO> listDept(String deptId, String userId)
    {
        String spaceId = userContextManager.getWorkspaceId(userId);

        if (StringUtil.isNullOrSpace(deptId))
        {
            deptId = AuthConstant.DEFAULT_PARENT_DEPT_ID;
        }
        List<DepartmentVO> result = new ArrayList<>();
        List<DepartmentDO> list = departmentMapper.queryList(deptId, spaceId);
        for (DepartmentDO departmentDO : list)
        {
            DepartmentVO departmentVO = new DepartmentVO();

            BeanUtils.copyProperties(departmentDO, departmentVO);

            result.add(departmentVO);
        }
        return result;
    }

    /**
     * 查询机构信息
     *
     * @param id String
     * @return DepartmentVO
     */
    public DepartmentVO item(String id)
    {
        DepartmentDO departmentDO = departmentMapper.selectById(id);
        if (departmentDO == null)
        {
            LogHelper.debug("部门信息返回为空！");
            return null;
        }
        DepartmentVO departmentVO = new DepartmentVO();
        BeanUtils.copyProperties(departmentDO, departmentVO);
        return departmentVO;
    }

    /**
     * 添加部门
     *
     * @param departmentVO DepartmentVO
     * @param spaceId String
     * @return ErrorCode
     */
    public ErrorCode insert(DepartmentVO departmentVO, String spaceId)
    {
        DepartmentDO departmentDO = new DepartmentDO();
        BeanUtils.copyProperties(departmentVO, departmentDO);
        departmentDO.setSpaceId(spaceId);

        if (StringUtil.isNullOrEmpty(departmentDO.getParentId()))
        {
            departmentDO.setParentId(AuthConstant.DEFAULT_PARENT_DEPT_ID);
        }

        //判断部门名称是否被占用
        int exist = departmentMapper.checkName(departmentDO);
        if (0 < exist)
        {
            LogHelper.error("同级下部门名称“"+departmentDO.getName()+"”已存在！",ErrorCode.DeptNameExist.getCode());
            return ErrorCode.DeptNameExist;
        }

        //生成新的部门编号，如果返回空，则生成失败（部门编号最高999）
        String deptCode = this.createDeptCode(departmentDO.getParentId(), departmentDO.getSpaceId());
        if (StringUtil.isNullOrEmpty(deptCode))
        {
            LogHelper.error("同级下部门CODE已经最大！",ErrorCode.FailedToNewCode.getCode());
            return ErrorCode.FailedToNewCode;
        }

        departmentDO.setCode(deptCode);
        departmentDO.setLeaf(AuthConstant.DEFAULT_DEPARTMENT_LEAF);//默认新增的机构为叶子节点

        int ret = departmentMapper.insert(departmentDO);
        if (0 >= ret)
        {
            LogHelper.error("新增部门失败！",ErrorCode.FailedToInsertRecord.getCode());
            return ErrorCode.FailedToInsertRecord;
        }

        return afterInsert(departmentDO);
    }

    /**
     * 添加完成之后<br />
     * 校验上级部门状态（leaf）是否为叶节点,如果不是叶节点状态，则需要更改状态
     * @param departmentDO DepartmentDO
     * @return ErrorCode
     */
    private  ErrorCode afterInsert(DepartmentDO departmentDO)
    {
        //如果上级ID不为0，则判断是否要更改上级的leaf
        if (AuthConstant.DEFAULT_PARENT_DEPT_ID.equals(departmentDO.getParentId()))
        {
            LogHelper.debug("新增部门为一级部门！");
            return ErrorCode.Success;
        }

        DepartmentDO parentDO = departmentMapper.selectById(departmentDO.getParentId());

        if (parentDO.getLeaf() == AuthConstant.DEFAULT_DEPARTMENT_LEAF)
        {
            DepartmentDO updateDO = new DepartmentDO();
            updateDO.setId(departmentDO.getParentId());
            updateDO.setLeaf(0);
            int retUpdate = departmentMapper.update(updateDO);
            if (0 >= retUpdate)
            {
                LogHelper.error("新增部门成功，修改上级部门状态为父节点失败！",ErrorCode.FailedToUpdateRecord.getCode());
                return ErrorCode.FailedToUpdateRecord;
            }
        }
        return  ErrorCode.Success;
    }

    /**
     * 修改机构信息
     *
     * @param departmentVO
     * @return
     */
    public ErrorCode update(DepartmentVO departmentVO)
    {
        DepartmentDO beforeDO = departmentMapper.selectById(departmentVO.getId());
        if(null==beforeDO)
        {
            LogHelper.error("目标数据不存在！",ErrorCode.FailedToUpdateRecord.getCode());
            return ErrorCode.FailedToUpdateRecord;
        }

        if(beforeDO.getName().equals(departmentVO.getName()))
        {
            LogHelper.debug(departmentVO.getName()+"与原名称相同！");
            return ErrorCode.Success;
        }
        beforeDO.setName(departmentVO.getName());

        //判断部门名称是否被占用
        int exist = departmentMapper.checkName(beforeDO);
        if (0 < exist)
        {
            LogHelper.error("同级下部门名称“"+beforeDO.getName()+"”已存在！",ErrorCode.DeptNameExist.getCode());
            return ErrorCode.DeptNameExist;
        }

        int ret = departmentMapper.update(beforeDO);
        if (0 >= ret)
        {
            LogHelper.error("修改目标数据失败！",ErrorCode.FailedToUpdateRecord.getCode());
            return ErrorCode.FailedToUpdateRecord;
        }
        return ErrorCode.Success;
    }

    /**
     * 删除组织机构
     * @param id String
     * @param spaceId String
     * @param nameRef Ref<List<String>>
     * @return ErrorCode
     */
    public ErrorCode removeByCode(String id, String spaceId,Ref<List<String>> nameRef)
    {
        DepartmentDO departmentDO = departmentMapper.selectById(id);

        if (null == departmentDO)
        {
            LogHelper.debug("目标数据不存在！");
            return ErrorCode.Success;
        }
        
        boolean referenced = checkRolesReferenced(id, spaceId);
        if(referenced) {
            List<String> names = new ArrayList<String>();
            names.add(departmentDO.getName());
            nameRef.set(names);
            LogHelper.error("部门下存在角色", ErrorCode.FailedToRemoveRecord.getCode());
            return ErrorCode.FailedToRemoveRecord;
        }
        
        //查询部门下有员工的部门名称
        List<String> names = beforeRemove(departmentDO.getCode(), spaceId);

        if (!ListUtil.isNullOrEmpty(names))
        {
            nameRef.set(names);
            LogHelper.error(nameRef.get()+"部门下存在用户",ErrorCode.FailedToRemoveRecord.getCode());
            return ErrorCode.FailedToRemoveRecord;
        }
        
        departmentMapper.removeByCode(departmentDO);
        return afterRemove(departmentDO);
    }
    
    private boolean checkRolesReferenced(String id, String spaceId) {
        int count = roleMapper.selectRolesReferencedCount(id, spaceId);
        return count > 0;
    }

    /**
     * 删除成功，判断删除成功之后，是否需要改变上级部门的状态<br />
     * 上级ID下如果不存在其他子级部门，则更改状态（leaf）为叶节点
     * @param departmentDO DepartmentDO
     * @return ErrorCode
     */
    private  ErrorCode afterRemove(DepartmentDO departmentDO)
    {
        //如果删除的是一级部门，则上级部门ID为0，返回成功
        if(AuthConstant.DEFAULT_PARENT_DEPT_ID.equals(departmentDO.getParentId()))
        {
            LogHelper.debug("被删除部门为一级部门！");
            return ErrorCode.Success;
        }

        List<DepartmentDO> departmentDOs = departmentMapper.queryList(departmentDO.getParentId(), null);

        if(ListUtil.isNullOrEmpty(departmentDOs))
        {
            DepartmentDO parent = new DepartmentDO();
            parent.setId(departmentDO.getParentId());
            parent.setLeaf(AuthConstant.DEFAULT_DEPARTMENT_LEAF);
            departmentMapper.update(parent);
        }
        return  ErrorCode.Success;
    }

    /**
     * 删除前校验，该部门以及下级部门是否为空
     * @param code String
     * @param spaceId String
     * @return List
     */
    public List<String> beforeRemove(String code,String spaceId)
    {
        DepartmentDO record = new DepartmentDO();
        record.setCode(code);
        record.setSpaceId(spaceId);
        List<String> names = new ArrayList<>();

        List<DepartmentDO> deptDOs = departmentMapper.selectDeptNotEmpty(record);

        if (ListUtil.isNullOrEmpty(deptDOs))
        {
            return new ArrayList<>();
        }

        for (DepartmentDO departmentDO : deptDOs)
        {
            if (null == departmentDO)
            {
                continue;
            }
            names.add(departmentDO.getName());
        }
        return names;
    }

    /**
     * 根据条件查询部门列表
     *
     * @param departmentVO 查询条件
     * @return List<DepartmentVO>
     */
    public List<DepartmentVO> queryDeptList(DepartmentVO departmentVO)
    {
        DepartmentDO departmentDO = new DepartmentDO();
        List<DepartmentVO> result = new ArrayList<>();

        BeanUtils.copyProperties(departmentVO, departmentDO);


        List<DepartmentDO> list = departmentMapper.queryDeptList(departmentDO);
        for (DepartmentDO tempDO : list)
        {
            DepartmentVO tempVO = new DepartmentVO();

            BeanUtils.copyProperties(tempDO, tempVO);

            result.add(tempVO);
        }
        return result;
    }

    /**
     * 根据机构 ID获取机构名称以及上级机构名称（）
     *
     * @param deptId String
     * @return String
     */
    public String queryFullDeptName(String deptId)
    {

        if("0".equals(deptId))
        {
            return "";
        }

        StringBuffer deptName = new StringBuffer();
        do
        {
            DepartmentVO departmentVO = item(deptId);
            if(null==departmentVO)
            {
                return "";
            }
            deptName.insert(0, departmentVO.getName());
            if ("0".equals(departmentVO.getParentId()) || "".equals(departmentVO.getParentId()))
            {
                break;
            }
            deptName.insert(0, "-");
            deptId = departmentVO.getParentId();
        }
        while (true);

        return deptName.toString();
    }

    /**
     * 创建部门编号<br/>
     * 如果编号达到999，则下一个编号返回空字符
     * @param parentId String
     * @return  String
     */
    public String createDeptCode(String parentId,String spaceId)
    {
        DepartmentDO departmentDO = departmentMapper.selectById(parentId);

        //获取同级别最后一个编号
        String lastCode = departmentMapper.queryLastCode(parentId, spaceId);

        if (StringUtil.isNullOrEmpty(lastCode))
        {
            if ("0".equals(parentId))
            {
                //此次添加的部门为一级部门
                return "001";
            }
            return departmentDO.getCode() + "001";
        }

        int codeLength = lastCode.length();

        String begin = lastCode.substring(0, codeLength - 3);//开头
        String end = lastCode.substring(codeLength - 3);//结尾3位数

        if ("999".equals(end))
        {
            return "";//此时为异常状态，需要调用端处理
        }

        String newCode = String.valueOf(Integer.valueOf(end) + 1);//新的结尾三位数

        int mark = end.length() - newCode.length();

        if (mark > 0)
        {
            for (; mark > 0; mark--)
            {
                newCode = "0" + newCode;
            }
        }
        return begin + newCode;
    }

}
